package com.heima.comment.service.impl;

import com.heima.aliyun.GreenTextScan;
import com.heima.comment.service.CommentHotService;
import com.heima.comment.service.CommentService;
import com.heima.common.exception.CustException;
import com.heima.feigns.user.UserFeign;
import com.heima.model.comment.dtos.CommentDto;
import com.heima.model.comment.dtos.CommentLikeDto;
import com.heima.model.comment.dtos.CommentSaveDto;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentLike;
import com.heima.model.comment.vos.ApCommentVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.threadlocal.AppUserThreadLocalUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class CommentServiceImpl implements CommentService {
    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    UserFeign userFeign;
    @Autowired
    GreenTextScan greenTextScan;
    @Autowired
    CommentHotService commentHotService;

    /**
     * 保存评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveComment(CommentSaveDto dto) {
        //参数校验
        if (dto == null) {
            CustException.cust(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //判断用户是否登录，只有登录用户可以发表评论
        ApUser user = AppUserThreadLocalUtils.getUser();
        if (user == null) {
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN, "需要先登录再评论");
        }
        //判断评论是否符合条件
        if(StringUtils.isBlank(dto.getContent())||dto.getContent().length()>140){
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID,"评论内容不符合要求，不能为空或字数超出140");
        }
        //远程调用方法查询用户姓名
        ApUser apUser = userFeign.findUserById(Long.valueOf(user.getId()));
        if (apUser == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "用户信息不存在");
        }
        //阿里云校验文本内容
        try {
            Map map = greenTextScan.greenTextScan(dto.getContent());
            if(!"pass".equals(map.get("suggestion"))){
                CustException.cust(AppHttpCodeEnum.SERVER_ERROR,"阿里云文本审核失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            CustException.cust(AppHttpCodeEnum.SERVER_ERROR,"阿里云文本审核失败");
        }

        //封装参数
        ApComment apComment = new ApComment();
        apComment.setAuthorId(user.getId());
        apComment.setAuthorName(apUser.getName());
        apComment.setEntryId(dto.getArticleId());
        apComment.setType((short) 0);
        apComment.setContent(dto.getContent());
        apComment.setImage(user.getImage());
        apComment.setLikes(0);
        apComment.setReply(0);
        apComment.setFlag((short) 0);
        apComment.setCreatedTime(new Date());
        apComment.setUpdatedTime(new Date());
        //将数据存储到mongodb中
        mongoTemplate.insert(apComment);
        return ResponseResult.okResult();
    }

    /**
     * 点赞评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentLikeDto dto) {
        //参数校验
        if (dto == null || dto.getCommentId() == null || dto.getOperation() == null) {
            CustException.cust(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //判断用户是否登录
        ApUser user = AppUserThreadLocalUtils.getUser();
        if (user == null) {
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN);
        }
        //根据评论id获取评论数据
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        if(apComment==null){
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST,"评论数据不存在");
        }
        Integer likes = apComment.getLikes();

        //判断用户是否点过赞
        Query query = Query.query(Criteria.where("authorId")
                .is(user.getId()).and("commentId").is(dto.getCommentId()));
        ApCommentLike apCommentLike = mongoTemplate.findOne(query, ApCommentLike.class);

        //判断用户是点赞评论还是取消点赞
        if (dto.getOperation() == (short) 0) {//点赞评论
            if (apCommentLike != null) {
                CustException.cust(AppHttpCodeEnum.DATA_EXIST, "请勿重复点赞");
            }
            apCommentLike = new ApCommentLike();
            apCommentLike.setAuthorId(user.getId());
            apCommentLike.setCommentId(dto.getCommentId());
            apCommentLike.setOperation(dto.getOperation());
            mongoTemplate.insert(apCommentLike);
            ++likes;

        } else {//取消点赞
            if(apCommentLike==null){
                CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST,"已经取消点赞了");
            }
            mongoTemplate.remove(apCommentLike);
            likes=likes>0 ? --likes:likes;
        }
        //修改评论点赞数
        apComment.setLikes(likes);
        mongoTemplate.save(apComment);
        //判断是否符合热点文章的要求
        if(likes>=5&&apComment.getFlag()==0){
            commentHotService.hotCommentExecutor(apComment.getEntryId(), apComment);
        }
        //封装点赞数返回响应
        Map resultMap = new HashMap();
        resultMap.put("likes",likes);
        return ResponseResult.okResult(resultMap);
    }

    /**
     * 根据文章id查询评论
     * @param dto
     * @return
     */
    @Override
    public ResponseResult findByArticleId(CommentDto dto) {
        //参数校验
        if(dto==null||dto.getArticleId()==null){
            CustException.cust(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        dto.checkParam();
        int size=dto.getSize();
        List<ApComment> commentList=new ArrayList<>();
        //判断是不是第一次查询
        if(dto.getIndex()==1){
            Query query = Query.query(Criteria.where("entryId")
                    .is(dto.getArticleId())
                    .and("flag").is((short)1))
                    .with(Sort.by(Sort.Direction.DESC,"likes"));
            commentList = mongoTemplate.find(query, ApComment.class);
            //设置后续查询大小
            size = dto.getSize() - commentList.size();
        }
        Query query = Query.query(Criteria.where("entryId")
                .is(dto.getArticleId())
                .and("createdTime")
                .lt(dto.getMinDate())
                .and("flag").is((short)0))
                .with(Sort.by(Sort.Direction.DESC,"createdTime")).limit(size);
        List<ApComment> normalCommentList = mongoTemplate.find(query, ApComment.class);

        if(commentList==null){//热门评论为空
            commentList=normalCommentList;
        }else {
            //将后续的普通评论添加到集合中
            commentList.addAll(normalCommentList);
        }
        //没有评论直接返回
        if(commentList==null||commentList.size()==0){
            return ResponseResult.okResult();
        }
        //先判断当前用户登录状态
        ApUser user = AppUserThreadLocalUtils.getUser();
        if(user==null){//未登录直接返回
            return ResponseResult.okResult(commentList);
        }
        //登录了则判断这些评论中哪些用户点赞过
        //获取当前评论中评论id
        ArrayList<ApCommentVo> apCommentVoList = new ArrayList<>();
        commentList.stream().forEach(comment->{
            //创建返回给前端的vo对象
            ApCommentVo apCommentVo = new ApCommentVo();
            BeanUtils.copyProperties(comment,apCommentVo);

            //判断当前评论，登录用户是否点赞过
            ApCommentLike apCommentLike = mongoTemplate.findOne(Query.query(Criteria.where("commentId")
                    .is(comment.getId()).and("authorId").is(user.getId())), ApCommentLike.class);
            if(apCommentLike!=null){
                apCommentVo.setOperation((short)0);
            }
            apCommentVoList.add(apCommentVo);
        });
        return ResponseResult.okResult(apCommentVoList);
    }
}
